<?php
declare (strict_types = 1);

namespace app\middleware;

use think\facade\Request;

/**
 * 验证API token
 */
class CheckClientSign
{
    protected $allowAccessNotSignList = ['/v1/upload-avatar'];

    /**
     * 处理请求
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        if( config('api.sign_auth') == false ){
            return $next($request);
        }

        if( in_array($request->url(),$this->allowAccessNotSignList) ){
            return $next($request);
        }

        $param = $request->param();
        // 验证请求签名
        if( !isset($param['sign']) || empty($param['sign']) ){
            api_response(400,'缺少访问签名');
        }

        // 验证接口时限
        if( !isset($param['time']) || time() - $param['time'] > config('api.timeout_second') ){
            api_response(400,'接口请求超时');
        }

        $clientSign = $param['sign'];
        $serverSign = self::buildSign($param);
        
        if( $clientSign !== $serverSign ){
            self::return_msg('无效的接口签名');
        }

        return $next($request);
    }

    /**
     * 创建签名
     * @param string $request_url 
     * @param array $param 请求参数
     */
    protected static function buildSign(array $param)
    {
        unset($param['sign']);

        $hash = config('api.sign_hash');
        $param['apiKey'] = $hash(config('api.sign_key'));

        ksort($param);
        $stirng = urldecode(http_build_query($param));
        return $hash($stirng);
    }

    /**
     * 响应错误信息
     */
    protected static function return_msg($message)
    {
        $response['code']    = 403;
        $response['message'] = $message;
        exit(json_encode($response,JSON_UNESCAPED_UNICODE));
    }
}
